#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <cstdio>

void PrintPending(sigset_t &pending)
{
    std::cout << "curr process[" << getpid() << "] pending:";
    for (int signo = 31; signo >= 1; signo--)
    {
        if (sigismember(&pending, signo))
            std::cout << 1;
        else
            std::cout << 0;
    }
    std::cout << "\n";
}

void handler(int signo)
{
    std::cout << signo << "号吸信号被递达！！" << std::endl;
}
int main()
{
    // 0.捕捉2号信号
    signal(2, handler); // 自定义捕捉  handler 自定义函数，是一个地址
    signal(2, SIG_IGN); // 忽略一个信号  把1强转成sighandler_t类型
    signal(2, SIG_DFL); // 默认动作  把0强转成sighandler_t类型

    // 1.屏蔽2号信号
    sigset_t block_set, old_set;
    sigemptyset(&block_set);
    sigemptyset(&old_set);
    sigaddset(&block_set, SIGINT); // 到目前为止，没有修改当前进程的block表(只在用户栈上)
    // 1.1设置进入到进程的block表中
    sigprocmask(SIG_BLOCK, &block_set, &old_set); // 真正的修改当前进程的block表，完成了对2号信号的屏蔽

    int cnt = 15;
    while (true)
    {
        // 2.获取当前进程的pending信号集
        sigset_t pending;
        sigpending(&pending);

        // 3.打印pending信号集
        PrintPending(pending);

        cnt--;
        // 4.恢复对2号信号的屏蔽
        if (cnt == 0)
        {
            std::cout << "解除对二号信号的屏蔽！！！" << std::endl;
            sigprocmask(SIG_SETMASK, &old_set, &block_set);
        }
        sleep(1);
    }
    return 0;
}

// 位图结构
// struct bits
// {
//     uint32_t bits[400];
// };

// 40
// 40/(sizeof(uint32_t)*8) = 1 -> bits[1]
// 40%(sizeof(uint32_t)*8) = 8 -> bits[1]:8

// int main()
// {
//     sigset_t bits;// sigset_t Linux给用户提供的一个用户级的数据类型 禁止用户直接修改位图

//     return 0;
// }

// int Sum(int start, int end)
// {
//     int sum = 0;
//     for (int i = start; i <= end; i++)
//     {
//         sum /= 0;
//         sum += i;
//     }
//     return sum;
// }
// int main()
// {
//     // int total = Sum(0, 100);
//     // std::cout << "total: " << total << std::endl;
//     pid_t id=fork();
//     if(id==0)
//     {
//         sleep(1);
//         //child
//         Sum(0,100);
//         exit(0);
//     }
//     //father
//     int status=0;
//     pid_t rid=waitpid(id,&status,0);
//     if(rid==id)
//     {
//         printf("exit code:%d,exit sig:%d,core dump:%d\n",(status>>8)&0xff,status&0x7f,(status>>7)&0x1);
//     }
//     return 0;
// }
